require 'zpack'
require 'zdc.doc'
local zunpack=zunpack
local zpack=zpack
local strsub=string.sub
local var=require 'zsvc.var'

module(..., package.seeall)

local Packet= {}
local Packet_mt = {__metatable = {}, __index = Packet}

function new(params)
	local obj = setmetatable({}, Packet_mt)
	obj.buf=''
	obj.cur=1
	return obj
end

function Packet:Clear()
	self.buf=''
	self.cur=1
	self.header=nil
end
function Packet:Attach(buf)
	self.buf=buf
	self.cur=1
	self.header=nil
end
function Packet:GetBufAndPos()
	if self.cur>#self.buf then return end
	return self.buf,self.cur
end

function Packet:MoveToNext(pos)
	self.cur=pos
end

function Packet:ParseHeader()
	if self.header then return self.header end
	local h={}
	local buf=self.buf
	h.tag,h.ver=strsub(buf,1,2),strsub(buf,3,4)
	_,h.appid,h.size=zunpack(buf,'>H>I',5)
	self.header=h
	if h.tag~='GL' or not h.size then
		error'parse bad header'
	end
	return h
end

function Packet:GetCH()
	local buf,pos=self.buf,11
	local ch
	if #buf>pos then
		pos,ch=var.ReadTable(buf,pos)
	end
	return pos,ch or {}
end
function Packet:GetMsg()
	local buf,pos=self.buf,11
	local ch,bd
	if #buf>pos then
		pos,ch=var.ReadTable(buf,pos)
		if #buf>pos then
			pos,bd=var.ReadTable(buf,pos)
		end
	end
	return pos,{ch=ch or {}, bd=bd or {}}
end
function Packet:SetMsg(appid,chv,bdv)
	local ch,bd
	ch=var.WriteTable(chv)
	bd=var.WriteTable(bdv)
	self.buf='GL00' .. zpack('>H>I',appid,#ch+#bd) .. ch .. bd
end
function Packet:SetMsg2(appid,chv,bdv,pos)
	local ch,bd
	ch=var.WriteTable(chv) .. strsub(bdv,pos)
	self.buf='GL00' .. zpack('>H>I',appid,#ch) .. ch
end

function Packet:Print()
	return zdc.doc.hex_dump(self.buf)
end
